/*
 * Copyright (C) 2011-2018 ShenZhen iBOXSaaS Information Technology Co.,Ltd.
 * 
 * All right reserved.
 * 
 * This software is the confidential and proprietary information of iBOXSaaS Company of China.
 * ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only in
 * accordance with the terms of the contract agreement you entered into with iBOXSaaS inc.
 * 
 */

package com.iboxpay.open.gateway.filter;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.iboxpay.open.common.constants.LogEnums;
import org.iboxpay.open.common.utils.AccessLogUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import com.iboxpay.common.json.MapperUtils;
import com.iboxpay.open.gateway.utils.LogUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

/**
 * 
 * PostLogFilter.java
 * 
 * @author xuxiao
 * @date 2018/06/15
 */
@Component
public class PostLogFilter extends ZuulFilter {
    /**
     * Logger for this class
     */
    private static final Logger accessLoger = LoggerFactory.getLogger("access");

    private static final Logger interfaceLoger = LoggerFactory.getLogger("interface");

    private static final Logger remoteLoger = LoggerFactory.getLogger("client-interface");

    @Autowired
    private ProxyRequestHelper helper;

    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        String response = LogUtils.getResponseBody(context);
        String uri = context.getRequest().getRequestURI();
        String method = context.getRequest().getMethod();
        String transactionId = MDC.get(LogEnums.transactionId.getCode());
        remoteLoger.info("[{}] [HTTP] [response] - {} {}", uri, method, response);
        interfaceLoger.info("[{}] [HTTP] [response] - {} {}", uri, method, response);

        Map<String, String> accessMap = AccessLogUtils.getAccessMap(Long.parseLong(MDC.get(LogEnums.startTime.getCode())),
                System.currentTimeMillis(), MDC.get(LogEnums.serviceId.getCode()), transactionId,
                LogEnums.openAuth.getCode(), response, context.getRequest());
        accessLoger.info(MapperUtils.toJson(accessMap));

        Map<String, String> remoteAccessMap = new HashMap<>();
        remoteAccessMap.putAll(accessMap);
        fillRemoteAccessMap(remoteAccessMap, context);
        accessLoger.info(MapperUtils.toJson(remoteAccessMap));

        return null;
    }

    private void fillRemoteAccessMap(Map<String, String> remoteAccessMap, RequestContext context) {
        String remoteServiceId = "";
        URL url = context.getRouteHost();
        if (url == null) {
            remoteServiceId = (String)context.get(FilterConstants.SERVICE_ID_KEY);
        } else {
            remoteServiceId = url.getHost();
        }
        remoteAccessMap.put(LogEnums.remoteIp.getCode(), remoteServiceId);
        remoteAccessMap.put(LogEnums.serviceId.getCode(), this.helper.buildZuulRequestURI(context.getRequest()));
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

}
